package org.hit.burkun.index.term;

import java.util.Collection;
import java.util.HashMap;
import java.util.Map;

import org.hit.burkun.db.DBHelper;
import org.hit.burkun.entities.Entity.TYPE;
import org.hit.burkun.extract.FiledsToEntityMapper;
import org.hit.burkun.extract.FiledsToEntityMapper.FILED;
import org.hit.burkun.index.term.IndexSynonym.SynAndType;

/**
 * 基因symbol和ontology term 同义词
 * 
 * @author burkun
 * 
 */
public class ExtractGeneralSynonm {

	private DBHelper termDbh;
	private FiledsToEntityMapper mapper;

	public ExtractGeneralSynonm(DBHelper termDbh, FiledsToEntityMapper mapper) {
		this.termDbh = termDbh;
		this.mapper = mapper;
	}

	public Collection<IndexSynonym> getTermSet(boolean isParentChildSynonym) {
		// 不是假的
		Collection<String[]> res = getRawData();
		if (isParentChildSynonym) {
			// 适配Ontology的父子关系同义词
			return getSynonymsWithParent(res);
		} else {
			Collection<IndexSynonym> terms = getSynonyms(res);
			return terms;
		}
	}

	private Collection<String[]> getRawData() {
		termDbh.connectionDB();
		Collection<String[]> res = termDbh.queryData(
				mapper.buildQueryAllData(), mapper.getFiledsSize());
		termDbh.disconnection();
		return res;
	}

	private Collection<IndexSynonym> getSynonymsWithParent(
			Collection<String[]> rawData) {
		if (mapper.getType() == TYPE.DISEASE_ONTOLOGY
				|| mapper.getType() == TYPE.GENE_ONTOLOGY
				|| mapper.getType() == TYPE.HP_ONTOLOGY) {
			/*
			 * fileds.put(FILED.DBID, "source1"); fileds.put(FILED.DEF,
			 * "term1_name"); fileds.put(FILED.NAME, "term2_name");
			 * fileds.put(FILED.OTHER, "rel_type"); fileds.put(FILED.PRIMARY_ID,
			 * "source2");
			 */
			Map<String, IndexSynonym> map = new HashMap<>();
			for (String[] line : rawData) {
				// 每个primary_id对应一个map，这个map中存的是IndexSynoym
				int isource1 = mapper.getResultIdxByFiled(FILED.PRIMARY_ID);
				int ioffical = mapper.getResultIdxByFiled(FILED.NAME);
				int isyn = mapper.getResultIdxByFiled(FILED.DEF);
				int isource2 = mapper.getResultIdxByFiled(FILED.DBID);
				// int itype = mapper.getResultIdxByFiled(FILED.OTHER);
				String source1 = line[isource1];
				String syn = line[isyn];
				String offical = line[ioffical];
				String synType = "NARROW";
				String source2 = line[isource2];

				if (map.containsKey(isource1)) {
					map.get(isource1).synonyms.add(new SynAndType(syn, synType,
							source2));
				} else {
					IndexSynonym is = new IndexSynonym();
					is.officalName = offical;
					is.synonyms.add(new SynAndType(syn, synType, source2));
					is.sourceID = source1;
					map.put(source1, is);
				}
			}
			return map.values();
		}
		return null;
	}

	private Collection<IndexSynonym> getSynonyms(Collection<String[]> rawData) {
		if (mapper.getType() == TYPE.DISEASE_ONTOLOGY
				|| mapper.getType() == TYPE.GENE_ONTOLOGY
				|| mapper.getType() == TYPE.HP_ONTOLOGY) {
			// 是三个ontology, 返回数据格式：primary_id, acc, synonym, alter_synonym
			Map<String, IndexSynonym> map = new HashMap<>();
			for (String[] line : rawData) {
				// 每个primary_id对应一个map，这个map中存的是IndexSynoym
				int ipid = mapper.getResultIdxByFiled(FILED.PRIMARY_ID);
				int iname = mapper.getResultIdxByFiled(FILED.NAME);
				int isyn = mapper.getResultIdxByFiled(FILED.DEF);
				int ialter = mapper.getResultIdxByFiled(FILED.DBID);
				int iother = mapper.getResultIdxByFiled(FILED.OTHER);
				String pid = line[ipid];
				String syn = line[isyn];
				String alter = line[ialter];
				String name = line[iname];
				String synType = line[iother];
				if (map.containsKey(pid)) {
					if (syn == null || syn.length() == 0) {
						map.get(pid).synonyms.add(new SynAndType(alter,
								synType, pid));
					} else {
						map.get(pid).synonyms.add(new SynAndType(syn, synType,
								pid));
					}
				} else {
					IndexSynonym is = new IndexSynonym();
					is.officalName = name;
					if (syn == null || syn.length() == 0) {
						is.synonyms.add(new SynAndType(alter, synType, pid));
					} else {
						is.synonyms.add(new SynAndType(syn, synType, pid));
					}
					is.sourceID = pid;
					map.put(pid, is);
				}
			}
			return map.values();
		} else if (mapper.getType() == TYPE.GENE_SYMBOL) {
			// 是基因符号
			/*
			 * fileds.put(FILED.DBID, "entrez_gene_id"); fileds.put(FILED.DEF,
			 * "synonyms"); fileds.put(FILED.NAME, "approved_symbol");
			 * fileds.put(FILED.PRIMARY_ID, "primary_id");
			 */
			Map<String, IndexSynonym> map = new HashMap<>();
			for (String[] line : rawData) {
				// 每个primary_id对应一个map，这个map中存的是IndexSynoym
				int ipid = mapper.getResultIdxByFiled(FILED.PRIMARY_ID);
				int iname = mapper.getResultIdxByFiled(FILED.NAME);
				int isyn = mapper.getResultIdxByFiled(FILED.DEF);
				String pid = line[ipid];
				String syn = line[isyn];
				String name = line[iname];
				if (map.containsKey(pid)) {
					if (syn != null && syn.length() != 0) {
						String[] ss = syn.split(",");
						for (String s : ss) {
							map.get(pid).synonyms.add(new SynAndType(s,
									"EXACT", pid));
						}
					}
				} else {
					IndexSynonym is = new IndexSynonym();
					is.officalName = name;
					if (syn != null && syn.length() != 0) {
						String[] ss = syn.split(",");
						for (String s : ss) {
							is.synonyms.add(new SynAndType(s, "EXACT", pid));
						}
					}
					is.sourceID = pid;
					map.put(pid, is);
				}
			}
			return map.values();
		}
		return null;
	}

}
